package com.york.tinyrpc.protoss.springboot.startert.bootstrap;

import com.york.tinyrpc.protoss.TinyRpcApplication;
import com.york.tinyrpc.protoss.config.RegistryCenterConfig;
import com.york.tinyrpc.protoss.config.TinyRpcConfig;
import com.york.tinyrpc.protoss.model.ServiceMetaInfo;
import com.york.tinyrpc.protoss.registry.LocalRegistry;
import com.york.tinyrpc.protoss.registry.center.RegistryCenter;
import com.york.tinyrpc.protoss.registry.center.RegistryCenterFactory;
import com.york.tinyrpc.protoss.springboot.startert.annotation.TinyRpcService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * TinyRpc 服务提供者启动
 * 实现BeanPostProcessor接口的postProcessAfterInitialization
 * 相当于后置，当初始化以后要做的事情
 */
public class TinyRpcProviderBootstrap implements BeanPostProcessor {

    /**
     * Bean 初始化后执行，注册服务
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> beanClass = bean.getClass();
        TinyRpcService rpcService = beanClass.getAnnotation(TinyRpcService.class);
        if (rpcService != null) {
            // 需要注册服务
            // 1. 获取服务基本信息
            Class<?> interfaceClass = rpcService.interfaceClass();
            // 默认值处理
            if (interfaceClass == void.class) {
                interfaceClass = beanClass.getInterfaces()[0];
            }
            String serviceName = interfaceClass.getName();
            String serviceVersion = rpcService.serviceVersion();
            // 2. 注册服务
            // 本地注册
            LocalRegistry.register(serviceName, beanClass);

            // 全局配置
            final TinyRpcConfig rpcConfig = TinyRpcApplication.getRpcConfig();
            // 注册服务到注册中心
            RegistryCenterConfig registryCenterConfig = rpcConfig.getRegistryCenterConfig();
            RegistryCenter registryCenter =
                    RegistryCenterFactory.getRegistryCenterByType(registryCenterConfig.getRegistryCenterType());

            // 构造服务信息
            ServiceMetaInfo serviceMetaInfo = ServiceMetaInfo.builder()
                    .serviceName(serviceName)
                    .serviceVersion(serviceVersion)
                    .serviceHost(rpcConfig.getServerHost())
                    .servicePort(rpcConfig.getServerPort())
                    .build();

            // 注册服务到注册中心
            try {
                registryCenter.serviceRegister(serviceMetaInfo);
            } catch (Exception e) {
                throw new RuntimeException(serviceName + " 服务注册失败", e);
            }
        }

        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}
